import { model, schema } from '@/utils/excel';
import { ITarget } from '../target/base/target';
import { kernel } from '@/ts/base';
import _ from 'lodash';
import { XForm, XReport } from '@/ts/base/schema';
import { Form, IForm } from '../thing/standard/form';
import { IReport, Report } from '../thing/standard/report';
import { FillChangedFields } from '@/utils/work';

function parseInstanceData(input: unknown): model.InstanceDataModel {
  if (input && typeof input === 'object') {
    return input as model.InstanceDataModel;
  }
  if (typeof input !== 'string') {
    return {} as model.InstanceDataModel;
  }
  const raw = input.trim();
  try {
    return JSON.parse(raw);
  } catch (_) {
    // 尝试进行常见兼容处理：补齐未加引号的键、单引号转双引号、去除尾逗号
    let s = raw;
    // 给未加引号的键名加双引号：key: value => "key": value
    s = s.replace(/([\{,\s])([a-zA-Z_][a-zA-Z0-9_-]*)\s*:/g, '$1"$2":');
    // 将单引号字符串替换为双引号
    s = s.replace(/'([^'\\]*(?:\\.[^'\\]*)*)'/g, (_m, g1) => '"' + g1.replace(/"/g, '\\"') + '"');
    // 去除对象或数组中的尾逗号
    s = s.replace(/,\s*([}\]])/g, '$1');
    try {
      return JSON.parse(s);
    } catch (_e) {
      // 仍失败则返回空对象，避免运行时错误
      return {} as model.InstanceDataModel;
    }
  }
}

export interface IInstance {
  // 任务
  tasks: schema.XWorkTask[];
  // 数据
  data: model.InstanceDataModel;
  // 加载任务
  loadTasks(reload?: boolean): Promise<schema.XWorkTask[]>;
  // 加载数据
  loadData(reload?: boolean): Promise<model.InstanceDataModel>;
  // 审批前处理数据
  dealInstanceData(data: model.InstanceDataModel): Promise<string>;
}

export class Instance implements IInstance {
  tasks: schema.XWorkTask[] = [];
  data: model.InstanceDataModel;
  target: ITarget;
  primaryForms: (IForm | IReport)[] = [];
  detailForms: IForm[] = [];
  instance: schema.XWorkInstance;
  _taskLoaded = false;
  _dataLoaded = false;

  constructor(_metadata: schema.XWorkInstance, target: ITarget) {
    this.instance = _metadata;
    this.target = target;
    this.data = parseInstanceData(_metadata.data);

    ///TODO: 待王阳确认后，删除
    if (this.data && this.data.primary) {
      const matchResult = _metadata.content?.match(/缴款单位:([^  ]+)/);
      const companyName = matchResult ? matchResult[1] : '未匹配到缴款单位';
      this.data.primary['507695596678990087'] = companyName;
    }
    ///
  }
  async loadTasks(reload: boolean = false): Promise<schema.XWorkTask[]> {
    if (reload || !this._taskLoaded) {
      this.instance.tasks = await kernel.LoadInstanceTask(
        this.instance.shareId,
        this.instance.belongId,
        this.instance.id,
        this.target.relations,
      );
      this._taskLoaded = true;
    }
    return this.instance.tasks || [];
  }
  async loadData(reload: boolean = false): Promise<model.InstanceDataModel> {
    if (reload || !this._dataLoaded) {
      if (!this.data) {
        var instance = await kernel.findInstance(
          this.instance.shareId,
          this.instance.belongId,
          this.instance.id,
          this.target.relations,
        );
        if (instance) {
          this.data = parseInstanceData(instance.data);
        }
      }
      if (this.data.node == undefined) {
        var result = await kernel.queryWorkNodes({
          id: this.instance.defineId,
          shareId: this.instance.defineShareId,
        });
        if (result.success) {
          await this.ParseWorkNode(result.data);
          this.data = { ...this.data, node: result.data };
          for (var form of [...this.primaryForms, ...this.detailForms]) {
            if (this.data.fields[form.id] == undefined) {
              this.data.fields[form.id] = await form.loadFields();
            }
          }
        }
      }
      this._dataLoaded = true;
    }
    return this.data;
  }

  async dealInstanceData(data: model.InstanceDataModel): Promise<string> {
    var json = '';
    FillChangedFields(data);
    for (var formId of Object.keys(data.data)) {
      var formData = data.data[formId].sort((a, b) =>
        a.createTime < b.createTime ? 1 : -1,
      )[0];
      if (formData.afterTempId && formData.afterTempId.length > 0) {
        var count = Math.ceil(formData.after.length / 200);
        var promises: Promise<model.ResultType<unknown>>[] = [];
        for (var index = 0; index < count; index++) {
          //写入数据
          promises.push(
            kernel.collectionReplace(
              this.target.id,
              this.target.belongId,
              this.target.relations,
              '-work-temp-data',
              formData.after.slice(index * 200, index * 200 + 200),
            ),
          );
        }
        await Promise.all(promises);
        formData.after = [];
      }
      if (formData.beforeTempId && formData.beforeTempId.length > 0) {
        formData.before = [];
      }
    }
    data.isNew = true;
    if (data.isNew) {
      json = JSON.stringify({ ...data, node: undefined, fields: {} });
    } else {
      json = JSON.stringify(data);
    }
    return json;
  }

  private async ParseWorkNode(node: model.WorkNodeModel) {
    node.primaryForms = [];
    node.detailForms = [];
    node.print = [];
    node.formRules = [];
    node.executors = [];
    node.buttons = [];
    node.forms = [];
    if (node.resource) {
      const resource = JSON.parse(node.resource);
      if (Array.isArray(resource)) {
        node.primaryForms = resource;
        node.formRules = [];
        node.executors = [];
      } else {
        node.primaryForms = resource.primaryForms ?? [];
        node.detailForms = resource.detailForms ?? [];
        node.forms = resource.forms ?? [];
        node.print = resource.print;
        node.formRules = resource.formRules;
        node.executors = resource.executors;
        node.buttons = resource.buttons;
        node.documentConfig = resource.documentConfig || {
          propMapping: {},
          nodeMapping: {},
          templates: [],
        };
        if (resource.forms) {
          node.detailForms = await this.target.directory.resource.formColl.find(
            resource.forms
              .filter((a: schema.XForm) => 'typeName' in a && a.typeName == '子表')
              .map((s: schema.XForm) => s.id),
          );
          const formsList = await this.target.directory.resource.formColl.find(
            resource.forms
              .filter((a: schema.XForm) => 'typeName' in a && a.typeName == '主表')
              .map((s: schema.XForm) => s.id),
          );
          const reportsList = await this.target.directory.resource.reportColl.find(
            resource.forms
              .filter((a: schema.XReport) => 'typeName' in a && a.typeName == '主表')
              .map((s: schema.XReport) => s.id),
          );
          node.primaryForms = [...formsList, ...reportsList];
        } else {
          resource.primaryForms && node.forms.push(...resource.primaryForms);
          resource.detailForms && node.forms.push(...resource.detailForms);
        }
      }
    }
    const formMap =
      node.forms.reduce<Dictionary<model.FormInfo>>((a, v) => {
        if (!a[v.id]) {
          // 检查id是否已经存在于a中
          a[v.id] = v; // 如果不存在，添加到a中
        }
        return a;
      }, {}) ?? {};
    node.detailForms = _.orderBy(node.detailForms, (a) => formMap[a.id]?.order);
    node.primaryForms = _.orderBy(node.primaryForms, (a) => formMap[a.id]?.order);
    for (const a of node.primaryForms) {
      if (a.typeName === '表单' || a.typeName === '报表') {
        this.primaryForms.push(
          new Form({ ...(a as XForm), id: a.id + '_' }, this.target.directory),
        );
      } else if (a.typeName === '表格') {
        this.primaryForms.push(
          new Report({ ...(a as XReport), id: a.id + '_' }, this.target.directory),
        );
      }
    }
    for (const a of node.detailForms) {
      this.detailForms.push(
        new Form({ ...(a as XForm), id: a.id + '_' }, this.target.directory),
      );
    }
    if (node.children) {
      await this.ParseWorkNode(node.children);
    }
    if (node.branches) {
      for (const branch of node.branches) {
        if (branch.children) {
          await this.ParseWorkNode(branch.children);
        }
      }
    }
  }
}
